package BLC

import (
	"flag"
	"fmt"
	"os"
)

type CLI struct {

}

//bc *BlockChain
func NewCLI() *CLI {
	return &CLI{}
}

//打印参数,打印要求的参数
func (cli *CLI) PrintUsage() {
	fmt.Println("Usage:")
	fmt.Println("getbalance -address ADDRESS <获得这个地址的余额>")
	fmt.Println("createblockchain -address ADDRESS <创建区块链并且把创世区块的东西奖励给挖矿地址")
	fmt.Println("printchain <打印整个区块链的内容>")
	fmt.Println("send -from FROM -to TO -amount AMOUNT <从from发送amount个代币给to>")
}

////打印整个区块链
func (cli *CLI) PrintBlockChain() {
	blockchain:=BlockChainObject()

	blockchain.ViewBlockChain()
}

////测试打包多个交易用的
//func (cli *CLI) sendToken() {
//	//tx1:=NewUTXOTransaction("lidabao","dandan",3,cli.blockchain)
//	tx2 := NewUTXOTransaction("lidabao", "awang", 2, cli.blockchain)
//
//	cli.blockchain.Miner([]*Transaction{tx2})
//
//	cli.blockchain.ViewBlockChain()
//}
//
////添加区块
//func (cli *CLI) AddBlock(data string) {
//	//cli.blockchain.AddBlock(data)
//	fmt.Println("正在添加新的区块...")
//	//cli.sendToken()
//
//	fmt.Println(cli.blockchain.FindSpentableOutputs("lidabao", 5))
//	fmt.Println(cli.blockchain.FindSpentableOutputs("dandan", 3))
//	fmt.Println(cli.blockchain.FindSpentableOutputs("awang", 2))
//	for _, transaction := range cli.blockchain.FindUnspentTransactions("lidabao") {
//		fmt.Println(*transaction)
//	}
//}

//验证参数的多少，避免数组越界问题
func (cli *CLI) ValidateAges() {
	if len(os.Args) < 2 {
		cli.PrintUsage()
		os.Exit(1)
	}
}

func (cli *CLI) Run() {
	cli.ValidateAges()
	createblockchain := flag.NewFlagSet("createblockchain", flag.ExitOnError)
	printBlock := flag.NewFlagSet("printchain", flag.ExitOnError)
	getbalance := flag.NewFlagSet("getbalance", flag.ExitOnError)
	send := flag.NewFlagSet("send", flag.ExitOnError)

	ginsitAddr := createblockchain.String("address", "", "这个是为了创建区块并且奖励给address地址")
	balanceAddr := getbalance.String("address", "", "这个是获取这个地址的余额")
	sendFrom := send.String("from", "", "这个是获取发送方的地址")
	sendTo := send.String("to", "", "这个是获取收取方的地址")
	sendAmount := send.Int("amount", 0, "这个是获取发送的总金额")

	switch os.Args[1] {
	case "createblockchain":

		err := createblockchain.Parse(os.Args[2:])
		if err != nil {
			panic(err)
		}

		CreateGenistBlockChain(*ginsitAddr)
		fmt.Println("区块链创建成功!!!")
	case "printchain":

		err := printBlock.Parse(os.Args[2:])
		if err != nil {
			fmt.Printf("%v\n", err)
		}

		fmt.Println("正在打印区块链的信息......")
		cli.PrintBlockChain()
	case "send":

		err := send.Parse(os.Args[2:])
		if err != nil {
			fmt.Println("%v\n", err)
		}

		cli.send(*sendFrom,*sendTo,*sendAmount)

	case "getbalance":

		err := getbalance.Parse(os.Args[2:])
		if err != nil {
			fmt.Println("%v\n", err)
		}

		fmt.Println("你的余额为:",GetBalance(*balanceAddr))
	default:

		cli.PrintUsage()

		fmt.Printf("请正确输入参数和命令！")
	}

	if createblockchain.Parsed() {
		if *ginsitAddr == "" {
			fmt.Printf("你没有输入地址进来!\n")
			createblockchain.Usage()
			os.Exit(1)
		} else {
			//cli.AddBlock(*data)
		}
	}

	if send.Parsed() {
		if *sendFrom == "" || *sendTo == "" || *sendAmount == 0 {
			fmt.Println("你的发送的参数填写有误")
			send.Usage()
			os.Exit(1)
		} else {
			fmt.Printf("from:%s,to:%s,amount:%d\n", *sendFrom, *sendTo, *sendAmount)
		}
	}

	if getbalance.Parsed() {
		if *balanceAddr == "" {
			fmt.Println("你的填写的东西有错误")
			getbalance.Usage()
			os.Exit(1)
		} else {
			fmt.Printf("balanceAddr:%s\n", *balanceAddr)
		}
	}
}
